package com.xin.di.uav.applet.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xin.di.uav.applet.mapper.PricingMapper;
import com.xin.di.uav.applet.mapper.PricingRuleMapper;
import com.xin.di.uav.applet.mapper.PricingRuleRangeMapper;
import com.xin.di.uav.applet.po.Pricing;
import com.xin.di.uav.applet.po.PricingRule;
import com.xin.di.uav.applet.po.PricingRuleRange;
import com.xin.di.uav.applet.resp.SpecialPricingResp;
import com.xin.di.uav.applet.resp.SysPricingResponse;
import com.xin.di.uav.applet.rest.PricingRuleRangeRest;
import com.xin.di.uav.applet.rest.PricingRuleRest;
import com.xin.di.uav.applet.rest.SpecialPricingRest;
import com.xin.di.uav.applet.service.IPricingService;
import com.xin.di.uav.common.enums.PricingRuleRangeTypeEnum;
import com.xin.di.uav.common.enums.PricingRuleTypeEnum;
import com.xin.di.uav.common.request.common.IdRequest;
import com.xin.di.uav.common.request.pricing.PricingAddRequest;
import com.xin.di.uav.common.request.pricing.PricingEditRequest;
import com.xin.di.uav.common.request.pricing.SpecialPricingReq;
import com.xin.di.uav.common.request.pricing.SysPricingRequest;
import com.xin.di.uav.common.utils.BeanUtil;
import com.xin.di.uav.common.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 计价表 服务实现类
 * </p>
 *
 * @author LTQ
 * @since 2023-05-19
 */
@Service
public class PricingServiceImpl extends ServiceImpl<PricingMapper, Pricing> implements IPricingService {

    @Autowired
    private PricingMapper pricingMapper;
    @Value("${express.fee:20}")
    private String expressFee;

    @Autowired
    private PricingRuleMapper pricingRuleMapper;

    @Autowired
    private PricingRuleRangeMapper pricingRuleRangeMapper;

    @Autowired
    private PricingRuleRest pricingRuleRest;

    @Autowired
    private PricingRuleRangeRest pricingRuleRangeRest;

    @Autowired
    private SpecialPricingRest specialPricingRest;

    private final Integer CONT_NUM = 0;

    private final Integer DEL_NUM = 1;
    private final String BASE_NUM_CHECK = "^[0-9]+(\\.[0-9]{1,1})?$";

    private final String ACCOUNT_NUM_CHECK = "^[0-9]+(\\.[0-9]{1,2})?$";


    private static final int DEFAULT_CAPACITY = 10;

    @Override
    public Pricing getPrice(String takeoffCode, String landingCode, Integer seconds) {
        QueryWrapper<Pricing> pricingQueryWrapper = new QueryWrapper<>();
        pricingQueryWrapper.eq("takeoff_code", takeoffCode);
        pricingQueryWrapper.eq("landing_code", landingCode);
        pricingQueryWrapper.lt("start_hour", seconds);
        pricingQueryWrapper.ge("end_hour", seconds);
        pricingQueryWrapper.eq("enable", true);
        Pricing pricing = pricingMapper.selectOne(pricingQueryWrapper);
        return pricing;
//        if (ObjectUtils.isEmpty(pricing)) {
//            return new BigDecimal(expressFee);
////            throw new BusinessException(ErrorEnum.PRICE_MISSING, "配置价格缺失");
//        }
//        BigDecimal price = pricing.getPrice();
//        //计算超范围加价格
//
//
//        return price;
    }

    @Override
    public Pricing getPriceByProductType(Byte productType, Integer seconds) {
        QueryWrapper<Pricing> pricingQueryWrapper = new QueryWrapper<>();
        pricingQueryWrapper.lambda().eq(Pricing::getProductType, productType).
                lt(Pricing::getStartHour, seconds).
                ge(Pricing::getEndHour, seconds).
                eq(Pricing::getEnable, true);
        return pricingMapper.selectOne(pricingQueryWrapper);
    }

    @Override
    public List<Pricing> getPriceByProductTypes(List<Byte> productTypes, Integer seconds) {
        QueryWrapper<Pricing> pricingQueryWrapper = new QueryWrapper<>();
        pricingQueryWrapper.lambda().in(Pricing::getProductType, productTypes).
                lt(Pricing::getStartHour, seconds).
                ge(Pricing::getEndHour, seconds).
                eq(Pricing::getEnable, true)
                .orderByAsc(Pricing::getSort);
        return pricingMapper.selectList(pricingQueryWrapper);
    }

    @Override
    public List<Pricing> getByProductTypes(List<Byte> productTypes) {
        QueryWrapper<Pricing> pricingQueryWrapper = new QueryWrapper<>();
        pricingQueryWrapper.lambda().in(Pricing::getProductType, productTypes).
                eq(Pricing::getEnable, true)
                .orderByAsc(Pricing::getSort);
        return pricingMapper.selectList(pricingQueryWrapper);
    }

    @Override
    public JSONObject calculateMarkup(double goodsWeight, BigDecimal jl, String pricingId, BigDecimal price) {
        JSONObject jsonObject = new JSONObject();
        QueryWrapper<PricingRule> pricingRuleQueryWrapper = new QueryWrapper<>();
        pricingRuleQueryWrapper.eq("pricing_id", pricingId);
        List<PricingRule> pricingRules = pricingRuleMapper.selectList(pricingRuleQueryWrapper);
        List<String> pricingRuleIds = pricingRules.stream().map(PricingRule::getId).collect(Collectors.toList());
        List<PricingRuleRange> pricingRuleRanges = new ArrayList<>();
        if (!CollectionUtils.isEmpty(pricingRuleIds)) {
            QueryWrapper<PricingRuleRange> pricingRuleRangeQueryWrapper = new QueryWrapper<>();
            pricingRuleRangeQueryWrapper.in("pricing_rule_id", pricingRuleIds);
            pricingRuleRanges = pricingRuleRangeMapper.selectList(pricingRuleRangeQueryWrapper);
        }
        List<PricingRuleRange> finalPricingRuleRanges = pricingRuleRanges;
        BigDecimal overweightCharges = new BigDecimal(0);
        BigDecimal overDistanceCharges = new BigDecimal(0);
        for (PricingRule pricingRule : pricingRules) {
            String pricingRuleId = pricingRule.getId();
            BigDecimal baseNum = pricingRule.getBaseNum();

            List<PricingRuleRange> targetPricingRuleRanges = finalPricingRuleRanges.stream().filter(finalPricingRuleRange -> finalPricingRuleRange.getPricingRuleId().equals(pricingRuleId)).sorted(Comparator.comparingInt(PricingRuleRange::getSort)).collect(Collectors.toList());
            Byte type = pricingRule.getType();
            if (type.equals(PricingRuleTypeEnum.WEIGHT.getType())) {
                //重量
                if (new BigDecimal(goodsWeight).compareTo(baseNum) <= 0) {
                    //基础内不加价
                    continue;
                }
                for (PricingRuleRange targetPricingRuleRange : targetPricingRuleRanges) {
                    BigDecimal endNum = targetPricingRuleRange.getEndNum();
                    BigDecimal startNum = targetPricingRuleRange.getStartNum();
                    BigDecimal markupPrice = targetPricingRuleRange.getMarkupPrice();
                    Byte rangeTypes = targetPricingRuleRange.getRangeTypes();
                    BigDecimal diff = new BigDecimal(goodsWeight).subtract(startNum);
                    if (rangeTypes.equals(PricingRuleRangeTypeEnum.BETWEEN.getType())) {
                        if (new BigDecimal(goodsWeight).compareTo(endNum) <= 0) {
                            overweightCharges = overweightCharges.add(diff.multiply(markupPrice));
                            break;
                        } else {
                            overweightCharges = overweightCharges.add((endNum.subtract(startNum)).multiply(markupPrice));
                        }
                    } else if (rangeTypes.equals(PricingRuleRangeTypeEnum.GREATER_THAN.getType())) {
                        overweightCharges = overweightCharges.add(diff.multiply(markupPrice));
                        break;
                    }

                }
            } else if (type.equals(PricingRuleTypeEnum.DISTANCE.getType())) {
                //距离
                if (jl.compareTo(baseNum) <= 0) {
                    //基础内不加价
                    continue;
                }
                for (PricingRuleRange targetPricingRuleRange : targetPricingRuleRanges) {
                    BigDecimal endNum = targetPricingRuleRange.getEndNum();
                    BigDecimal startNum = targetPricingRuleRange.getStartNum();
                    BigDecimal markupPrice = targetPricingRuleRange.getMarkupPrice();
                    Byte rangeTypes = targetPricingRuleRange.getRangeTypes();
                    BigDecimal diff = jl.subtract(startNum);
                    if (rangeTypes.equals(PricingRuleRangeTypeEnum.BETWEEN.getType())) {
                        if (jl.compareTo(endNum) <= 0) {
                            overDistanceCharges = overDistanceCharges.add(diff.multiply(markupPrice));
                            break;
                        } else {
                            overDistanceCharges = overDistanceCharges.add((endNum.subtract(startNum)).multiply(markupPrice));
                        }
                    } else if (rangeTypes.equals(PricingRuleRangeTypeEnum.GREATER_THAN.getType())) {
                        overDistanceCharges = overDistanceCharges.add(diff.multiply(markupPrice));
                        break;
                    }
                }
            }

        }
        price = price.add(overDistanceCharges).add(overweightCharges);
        jsonObject.put("price", price.setScale(2, RoundingMode.HALF_UP));
        jsonObject.put("overweightCharges", overweightCharges);
        jsonObject.put("overDistanceCharges", overDistanceCharges);
        return jsonObject;
    }

    @Override
    public List<SysPricingResponse> getPricing(SysPricingRequest sysPricingRequest) {

//        QueryWrapper<Pricing> pricingQueryWrapper = new QueryWrapper<>();
//        String landingCode = sysPricingRequest.getLandingCode();
//        String takeoffCode = sysPricingRequest.getTakeoffCode();
//
//        if (!ObjectUtils.isEmpty(landingCode)) {
//            pricingQueryWrapper.and(wrapper -> wrapper.like("landing_code", landingCode).or().like("landing_name", landingCode));
//        }
//        if (!ObjectUtils.isEmpty(takeoffCode)) {
//            pricingQueryWrapper.and(wrapper -> wrapper.like("takeoff_code", takeoffCode).or().like("takeoff_name", takeoffCode));
//        }
//
//        pricingQueryWrapper.orderByDesc("update_time");
        Page<Pricing> pricingPage = new Page<>(sysPricingRequest.getPage(), sysPricingRequest.getSize());
//        IPage<Pricing> pricingIsPage = pricingMapper.selectPage(pricingPage, pricingQueryWrapper);
        IPage<SysPricingResponse> pricingIsPage = pricingMapper.findPage(pricingPage, sysPricingRequest.getProductType());
//        List<Pricing> pricingList = pricingIsPage.getRecords();
//        List<SysPricingResponse> sysPricingResponses = new ArrayList<>();
        if (CollUtil.isEmpty(pricingIsPage.getRecords())) {
            return null;
        }
        List<SysPricingResponse> pricingResponseList = pricingIsPage.getRecords();
        List<String> pricingIdList = pricingResponseList.stream().map(SysPricingResponse::getId).collect(Collectors.toList());
        List<PricingRule> pricingRuleList;
        if (!CollectionUtils.isEmpty(pricingIdList)) {
            pricingRuleList = pricingRuleRest.getPricingRuleListByIds(pricingIdList);
        } else {
            pricingRuleList = new ArrayList<>(DEFAULT_CAPACITY);
        }
        List<PricingRuleRange> pricingRuleRangeList;
        if (!CollectionUtils.isEmpty(pricingRuleList)) {
            List<String> pricingRuleIdList = pricingRuleList.stream().map(PricingRule::getId).collect(Collectors.toList());
            pricingRuleRangeList = pricingRuleRangeRest.getPricingRuleRangeByIds(pricingRuleIdList).stream().sorted(Comparator.comparingInt(PricingRuleRange::getSort)).collect(Collectors.toList());
        } else {
            pricingRuleRangeList = new ArrayList<>();
        }
        pricingResponseList.forEach(pricing -> {
//            SysPricingResponse sysPricingResponse = BeanUtil.copyProperties(pricing, SysPricingResponse.class);
//            if (!ObjectUtils.isEmpty(sysPricingResponse.getLandingName())) {
//                sysPricingResponse.setLandingCode(sysPricingResponse.getLandingCode() + "(" + sysPricingResponse.getLandingName() + ")");
//            }
//            if (!ObjectUtils.isEmpty(sysPricingResponse.getTakeoffName())) {
//                sysPricingResponse.setTakeoffCode(sysPricingResponse.getTakeoffCode() + "(" + sysPricingResponse.getTakeoffName() + ")");
//            }
            StringBuilder foundationWeightRule = new StringBuilder();
            StringBuilder foundationDistanceRule = new StringBuilder();
            List<SysPricingResponse.PricingRuleRange> pricingRuleRangeArray = new ArrayList<>();
            for (PricingRule pricingRule : pricingRuleList) {
                if (pricing.getId().equals(pricingRule.getPricingId())) {
                    if (PricingRuleTypeEnum.WEIGHT.getType().equals(pricingRule.getType())) {
                        foundationWeightRule.append("【").append(PricingRuleTypeEnum.WEIGHT.getName()).append("】").append(":").append("基础重量").append(pricingRule.getBaseNum()).append("kg");
                        SysPricingResponse.PricingRuleRange pricingRuleRange = new SysPricingResponse.PricingRuleRange();
                        pricingRuleRange.setPricingRuleId(pricingRule.getId());
                        pricingRuleRange.setType(PricingRuleTypeEnum.WEIGHT.getType());
                        pricingRuleRange.setBaseNum(pricingRule.getBaseNum());
                        pricingRuleRangeArray.add(pricingRuleRange);
                    }
                    if (PricingRuleTypeEnum.DISTANCE.getType().equals(pricingRule.getType())) {
                        foundationDistanceRule.append("【").append(PricingRuleTypeEnum.DISTANCE.getName()).append("】").append(":").append("基础距离").append(pricingRule.getBaseNum()).append("公里");
                        SysPricingResponse.PricingRuleRange pricingRuleRange = new SysPricingResponse.PricingRuleRange();
                        pricingRuleRange.setPricingRuleId(pricingRule.getId());
                        pricingRuleRange.setType(PricingRuleTypeEnum.DISTANCE.getType());
                        pricingRuleRange.setBaseNum(pricingRule.getBaseNum());
                        pricingRuleRangeArray.add(pricingRuleRange);
                    }
//                    sysPricingResponse.setTypes(types);
//                    sysPricingResponse.setBaseNums(baseNums);
//                    List<SysPricingResponse.WeightOrDistance> weightOrDistanceList =new ArrayList<>();
                    List<SysPricingResponse.PricingRuleRange.WeightOrDistance> weightOrDistanceList = new ArrayList<>();
                    for (PricingRuleRange pricingRuleRange : pricingRuleRangeList) {
                        if (pricingRule.getId().equals(pricingRuleRange.getPricingRuleId())) {
                            if (PricingRuleTypeEnum.WEIGHT.getType().equals(pricingRule.getType())) {
                                if (PricingRuleRangeTypeEnum.BETWEEN.getType().equals(pricingRuleRange.getRangeTypes())) {
                                    foundationWeightRule.append(",").append(pricingRuleRange.getStartNum()).append("-").append(pricingRuleRange.getEndNum()).append("kg").append("每kg加价").append(pricingRuleRange.getMarkupPrice()).append("元");
                                    SysPricingResponse.PricingRuleRange.WeightOrDistance weightOrDistance = new SysPricingResponse.PricingRuleRange.WeightOrDistance();
//                                SysPricingResponse.WeightOrDistance weightOrDistance = new SysPricingResponse.WeightOrDistance();
                                    weightOrDistance.setRangeTypes(PricingRuleRangeTypeEnum.BETWEEN.getType());
                                    weightOrDistance.setStartNum(pricingRuleRange.getStartNum());
                                    weightOrDistance.setEndNum(pricingRuleRange.getEndNum());
                                    weightOrDistance.setMarkupPrice(pricingRuleRange.getMarkupPrice());
                                    weightOrDistance.setSort(pricingRuleRange.getSort());
                                    weightOrDistance.setPricingRuleRangeId(pricingRuleRange.getId());
                                    weightOrDistanceList.add(weightOrDistance);
                                }
                                if (PricingRuleRangeTypeEnum.GREATER_THAN.getType().equals(pricingRuleRange.getRangeTypes())) {
                                    foundationWeightRule.append(",").append("大于").append(pricingRuleRange.getStartNum()).append("kg").append("每kg加价").append(pricingRuleRange.getMarkupPrice()).append("元");
                                    SysPricingResponse.PricingRuleRange.WeightOrDistance weightOrDistance = new SysPricingResponse.PricingRuleRange.WeightOrDistance();
                                    weightOrDistance.setRangeTypes(PricingRuleRangeTypeEnum.GREATER_THAN.getType());
                                    weightOrDistance.setStartNum(pricingRuleRange.getStartNum());
                                    weightOrDistance.setMarkupPrice(pricingRuleRange.getMarkupPrice());
                                    weightOrDistance.setSort(pricingRuleRange.getSort());
                                    weightOrDistance.setPricingRuleRangeId(pricingRuleRange.getId());
                                    weightOrDistanceList.add(weightOrDistance);
                                }
                                if (!CollectionUtils.isEmpty(pricingRuleRangeArray)) {
                                    for (int i = 0; i < pricingRuleRangeArray.size(); i++) {
                                        if (pricingRule.getType().equals(pricingRuleRangeArray.get(i).getType())) {
                                            pricingRuleRangeArray.get(i).setWeightOrDistanceList(weightOrDistanceList);
                                        }
                                    }
                                }
                            }
                            if (PricingRuleTypeEnum.DISTANCE.getType().equals(pricingRule.getType())) {
                                if (PricingRuleRangeTypeEnum.BETWEEN.getType().equals(pricingRuleRange.getRangeTypes())) {
                                    foundationDistanceRule.append(",").append(pricingRuleRange.getStartNum()).append("-").append(pricingRuleRange.getEndNum()).append("公里").append("每公里加价").append(pricingRuleRange.getMarkupPrice()).append("元");
                                    SysPricingResponse.PricingRuleRange.WeightOrDistance weightOrDistance = new SysPricingResponse.PricingRuleRange.WeightOrDistance();
//                                SysPricingResponse.WeightOrDistance weightOrDistance = new SysPricingResponse.WeightOrDistance();
                                    weightOrDistance.setRangeTypes(PricingRuleRangeTypeEnum.BETWEEN.getType());
                                    weightOrDistance.setStartNum(pricingRuleRange.getStartNum());
                                    weightOrDistance.setEndNum(pricingRuleRange.getEndNum());
                                    weightOrDistance.setMarkupPrice(pricingRuleRange.getMarkupPrice());
                                    weightOrDistance.setSort(pricingRuleRange.getSort());
                                    weightOrDistance.setPricingRuleRangeId(pricingRuleRange.getId());
                                    weightOrDistanceList.add(weightOrDistance);
                                }
                                if (PricingRuleRangeTypeEnum.GREATER_THAN.getType().equals(pricingRuleRange.getRangeTypes())) {
                                    foundationDistanceRule.append(",").append("大于").append(pricingRuleRange.getStartNum()).append("公里").append("每公里加价").append(pricingRuleRange.getMarkupPrice()).append("元");
                                    SysPricingResponse.PricingRuleRange.WeightOrDistance weightOrDistance = new SysPricingResponse.PricingRuleRange.WeightOrDistance();
                                    weightOrDistance.setRangeTypes(PricingRuleRangeTypeEnum.GREATER_THAN.getType());
                                    weightOrDistance.setStartNum(pricingRuleRange.getStartNum());
                                    weightOrDistance.setMarkupPrice(pricingRuleRange.getMarkupPrice());
                                    weightOrDistance.setSort(pricingRuleRange.getSort());
                                    weightOrDistance.setPricingRuleRangeId(pricingRuleRange.getId());
                                    weightOrDistanceList.add(weightOrDistance);
                                }
                                if (!CollectionUtils.isEmpty(pricingRuleRangeArray)) {
                                    for (int i = 0; i < pricingRuleRangeArray.size(); i++) {
                                        if (pricingRule.getType().equals(pricingRuleRangeArray.get(i).getType())) {
                                            pricingRuleRangeArray.get(i).setWeightOrDistanceList(weightOrDistanceList);
                                        }
                                    }
                                }
                            }
                        }

                    }
                }
            }
            pricing.setPricingRuleRangeArray(pricingRuleRangeArray);
            pricing.setPricingWeightRule(foundationWeightRule.toString());
            pricing.setPricingDistanceRule(foundationDistanceRule.toString());
            pricing.setPrice(pricing.getPrice().setScale(2, RoundingMode.HALF_UP));
            StringBuilder specialPricingText = new StringBuilder();
            if (CollUtil.isNotEmpty(pricing.getSpecialPricingResps())) {
                pricing.getSpecialPricingResps().forEach(item -> {
                    item.setPrice(item.getPrice().setScale(2, RoundingMode.HALF_UP));
                    specialPricingText.append("【航线】 ").append(item.getTakeoffName()).append(" - ").append(item.getLandingName()).append(" , ");
                    specialPricingText.append(item.getIsItBidirectional() == 1 ? "双向;" : "单向;");
                    specialPricingText.append("特殊定价 ").append(item.getPrice().setScale(2, RoundingMode.HALF_UP)).append(" 元;\n");
                });
            }
            pricing.setSpecialPricingText(specialPricingText.toString());
            for (SpecialPricingResp specialPricingResp : pricing.getSpecialPricingResps()) {
                if (!ObjectUtils.isEmpty(specialPricingResp.getLandingName())) {
                    specialPricingResp.setLandingCode(specialPricingResp.getLandingCode() + "(" + specialPricingResp.getLandingName() + ")");
                }
                if (!ObjectUtils.isEmpty(specialPricingResp.getTakeoffName())) {
                    specialPricingResp.setTakeoffCode(specialPricingResp.getTakeoffCode() + "(" + specialPricingResp.getTakeoffName() + ")");
                }
            }
//            sysPricingResponses.add(sysPricingResponse);
        });
        return pricingResponseList;
    }

    @Override
    public Long getTotal(SysPricingRequest sysPricingRequest) {
//        QueryWrapper<Pricing> pricingQueryWrapper = new QueryWrapper<>();
//        String landingCode = sysPricingRequest.getLandingCode();
//        String takeoffCode = sysPricingRequest.getTakeoffCode();
//
//        if (!ObjectUtils.isEmpty(landingCode)) {
//            pricingQueryWrapper.and(wrapper -> wrapper.like("landing_code", landingCode).or().like("landing_name", landingCode));
//        }
//        if (!ObjectUtils.isEmpty(takeoffCode)) {
//            pricingQueryWrapper.and(wrapper -> wrapper.like("takeoff_code", takeoffCode).or().like("takeoff_name", takeoffCode));
//        }
//        Long cnt = pricingMapper.selectCount(pricingQueryWrapper);
        Long cnt = pricingMapper.selectCount(new LambdaQueryWrapper<Pricing>()
                .eq(ObjectUtil.isNotNull(sysPricingRequest.getProductType()), Pricing::getProductType, sysPricingRequest.getProductType()));
        return cnt;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(PricingAddRequest pricingAddRequest) {
        Long l = pricingMapper.selectCount(new LambdaQueryWrapper<Pricing>().eq(Pricing::getEnable, 1).eq(Pricing::getProductType, pricingAddRequest.getProductType()));
        if (l > 0) {
            throw new RuntimeException("您保存的产品类型的定价已经存在，不可重复设置定价");
        }
        //没有传入配送时长就设置默认时长
        if (ObjectUtil.isNull(pricingAddRequest.getDeliveryTime())) {
            pricingAddRequest.setDeliveryTime(1d);
        }
        QueryWrapper<Pricing> pricingQueryWrapper = new QueryWrapper<>();
        pricingQueryWrapper.eq("takeoff_code", pricingAddRequest.getTakeoffCode());
        pricingQueryWrapper.eq("landing_code", pricingAddRequest.getLandingCode());
        pricingQueryWrapper.eq("enable", true);
        List<Pricing> pricingList = pricingMapper.selectList(pricingQueryWrapper);
        Integer startHour = pricingAddRequest.getStartHour();
        Integer endHour = pricingAddRequest.getEndHour();
        BigDecimal price = pricingAddRequest.getPrice();
        if (price.compareTo(new BigDecimal("99999.99")) > 1 || price.compareTo(new BigDecimal("0")) <= 0) {
            throw new RuntimeException("仅支持输入数字，支持小数，最多两位小数，输入范围(0,99999.99)");
        }
//        if (pricingAddRequest.getLandingCode().equals(pricingAddRequest.getTakeoffCode())) {
//            throw new RuntimeException("起飞点与降落点不能一致");
//        }
        if (startHour >= endHour) {
            throw new RuntimeException("开始时间不能大于等于结束时间");
        }
        for (Pricing pricing : pricingList) {
            Integer originalStartHour = pricing.getStartHour();
            Integer originalEndHour = pricing.getEndHour();
            if (!(startHour > originalEndHour || endHour < originalStartHour)) {
                String startDate = DateUtils.second2Time(originalStartHour.longValue());
                String endDate = DateUtils.second2Time(originalEndHour.longValue());
                throw new RuntimeException("存在时间段" + startDate + "-" + endDate + "重叠的定价数据，请核实后重新配置");
            }
        }
        Pricing pricing = BeanUtil.copyProperties(pricingAddRequest, Pricing.class);
        pricing.setEnable(true);
        String[] uuid = UUID.randomUUID().toString().split("-");
        String uuidKey = uuid[uuid.length - 2] + uuid[uuid.length - 1];
        pricing.setId(uuidKey);
        pricingMapper.insert(pricing);
        pricingAddRequest.setPricingId(uuidKey);
        List<String> pricingRuleIdList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(pricingAddRequest.getPricingRuleRangeArray())) {
            for (int i = 0; i < pricingAddRequest.getPricingRuleRangeArray().size(); i++) {
                pricingRuleIdList.add(String.join("", UUID.randomUUID().toString().split("-")));
            }
        }
        pricingAddRequest.setPricingRuleIds(pricingRuleIdList);
        pricingRuleRest.add(pricingAddRequest);
        pricingRuleRangeRest.add(pricingAddRequest);

        //检查特殊定价是否重复
        if (CollUtil.isNotEmpty(pricingAddRequest.getSpecialPricingReqList())) {
            assert !hasDuplicates(pricingAddRequest.getSpecialPricingReqList()) : "特殊定价存在重复航线";
            for (SpecialPricingReq specialPricingReq : pricingAddRequest.getSpecialPricingReqList()) {
                BigDecimal specialPricingPrice = specialPricingReq.getPrice();
                if (specialPricingPrice.compareTo(new BigDecimal("99999.99")) > 0 || specialPricingPrice.compareTo(new BigDecimal("0")) <= 0) {
                    throw new RuntimeException("特殊定价仅支持输入数字，支持小数，最多两位小数，输入范围(0,99999.99)");
                }
                specialPricingReq.setCreateTime(LocalDateTime.now());
                specialPricingReq.setUpdateTime(LocalDateTime.now());
                specialPricingReq.setPricingId(uuidKey);
                specialPricingReq.setId(String.join("", UUID.randomUUID().toString().split("-")));
            }
            if (!specialPricingRest.addBatchSpecialPricing(pricingAddRequest.getSpecialPricingReqList())) {
                throw new RuntimeException("定价保存失败");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(PricingEditRequest pricingEditRequest) {
        Long l = pricingMapper.selectCount(new LambdaQueryWrapper<Pricing>()
                .ne(Pricing::getId, pricingEditRequest.getId())
                .eq(Pricing::getEnable, 1)
                .eq(Pricing::getProductType, pricingEditRequest.getProductType()));
        if (l > 0) {
            throw new RuntimeException("您保存的产品类型的定价已经存在，不可重复设置定价");
        }
        if (ObjectUtil.isNull(pricingEditRequest.getId())) {
            throw new RuntimeException("编辑定价ID不能为空");
        }
        Optional.ofNullable(this.getById(pricingEditRequest.getId())).orElseThrow(() -> new RuntimeException("当前编辑的定价不存在"));

        QueryWrapper<Pricing> pricingQueryWrapper = new QueryWrapper<>();
        pricingQueryWrapper.eq("takeoff_code", pricingEditRequest.getTakeoffCode());
        pricingQueryWrapper.eq("landing_code", pricingEditRequest.getLandingCode());
        pricingQueryWrapper.ne("id", pricingEditRequest.getId());
        pricingQueryWrapper.eq("enable", true);
        List<Pricing> pricingList = pricingMapper.selectList(pricingQueryWrapper);
        Pricing pricing = pricingMapper.selectById(pricingEditRequest.getId());
        Integer startHour = pricingEditRequest.getStartHour();
        Integer endHour = pricingEditRequest.getEndHour();
        pricing.setEnable(true);
        if (ObjectUtils.isEmpty(pricing)) {
            throw new RuntimeException("记录不存在");
        }
        BigDecimal price = pricingEditRequest.getPrice();
        if (price.compareTo(new BigDecimal("99999.99")) > 1 || price.compareTo(new BigDecimal("0")) <= 0) {
            throw new RuntimeException("仅支持输入数字，支持小数，最多两位小数，输入范围(0,99999.99)");
        }
//        if (pricingEditRequest.getLandingCode().equals(pricingEditRequest.getTakeoffCode())) {
//            throw new RuntimeException("起飞点与降落点不能一致");
//        }
        if (startHour > endHour) {
            throw new RuntimeException("开始时间不能大于结束时间");
        }
        for (Pricing pricing1 : pricingList) {
            Integer originalStartHour = pricing1.getStartHour();
            Integer originalEndHour = pricing1.getEndHour();
            if (!(startHour > originalEndHour || endHour < originalStartHour)) {
                String startDate = DateUtils.second2Time(originalStartHour.longValue());
                String endDate = DateUtils.second2Time(originalEndHour.longValue());
                throw new RuntimeException("存在时间段" + startDate + "-" + endDate + "重叠的定价数据，请核实后重新配置");
            }
        }
        pricing.setProcessedBy(pricingEditRequest.getProcessedBy());
        pricing.setTakeoffCode(pricingEditRequest.getTakeoffCode());
        pricing.setProcessedBy(pricingEditRequest.getProcessedBy());
        pricing.setLandingCode(pricingEditRequest.getLandingCode());
        pricing.setLandingName(pricingEditRequest.getLandingName());
        pricing.setLandingCode(pricingEditRequest.getLandingCode());
        pricing.setUpdateTime(new Date());
        pricing.setStartHour(pricingEditRequest.getStartHour());
        pricing.setEndHour(pricingEditRequest.getEndHour());
        pricing.setPrice(pricingEditRequest.getPrice());
        pricing.setProductType(pricingEditRequest.getProductType());
        pricing.setProductTypeName(pricingEditRequest.getProductTypeName());
        pricingMapper.updateById(pricing);
        if (!CollectionUtils.isEmpty(pricingEditRequest.getPricingRuleRangeArray())) {
            for (PricingEditRequest.PricingRuleRange pricingRuleRange : pricingEditRequest.getPricingRuleRangeArray()) {
//                if (ObjectUtils.isEmpty(pricingRuleRange.getType())) {
//                    throw new RuntimeException("定价类型未传");
//                }
//
                if (DEL_NUM.equals(pricingRuleRange.getDelNum()) || pricingRuleRange.getType() == null) {
                    continue;
                }
                if (!ObjectUtils.isEmpty(pricingRuleRange.getType()) && (PricingRuleTypeEnum.WEIGHT.getType().equals(pricingRuleRange.getType()) || PricingRuleTypeEnum.DISTANCE.getType().equals(pricingRuleRange.getType()))) {
                    if (ObjectUtils.isEmpty(pricingRuleRange.getBaseNum()) || pricingRuleRange.getBaseNum().compareTo(BigDecimal.ZERO) == CONT_NUM || pricingRuleRange.getBaseNum().compareTo(BigDecimal.ZERO) < CONT_NUM) {
                        throw new RuntimeException("基础重量或基础距离不能为空或为0以及负数");
                    }
                    if (!pricingRuleRange.getBaseNum().toString().matches(BASE_NUM_CHECK)) {
                        throw new RuntimeException("基础重量或基础距离仅支持输入正数或一位小数");
                    }
                    if (!CollectionUtils.isEmpty(pricingRuleRange.getWeightOrDistanceList())) {
                        for (PricingEditRequest.PricingRuleRange.WeightOrDistance weightOrDistance : pricingRuleRange.getWeightOrDistanceList()) {
                            if (ObjectUtils.isEmpty(weightOrDistance.getRangeTypes())) {
                                throw new RuntimeException("区间或大于类型未传");
                            }
                            if (ObjectUtils.isEmpty(weightOrDistance.getStartNum()) || weightOrDistance.getStartNum().compareTo(BigDecimal.ZERO) == CONT_NUM || weightOrDistance.getStartNum().compareTo(BigDecimal.ZERO) < CONT_NUM) {
                                throw new RuntimeException("起始重量或起始距离不能为空或为0以及负数");
                            }
                            if (!weightOrDistance.getStartNum().toString().matches(BASE_NUM_CHECK)) {
                                throw new RuntimeException("基础重量或基础距离仅支持输入正数或一位小数");
                            }
                            if (PricingRuleRangeTypeEnum.BETWEEN.getType().equals(weightOrDistance.getRangeTypes())) {
                                if (ObjectUtils.isEmpty(weightOrDistance.getEndNum()) || weightOrDistance.getEndNum().compareTo(BigDecimal.ZERO) == CONT_NUM || weightOrDistance.getEndNum().compareTo(BigDecimal.ZERO) < CONT_NUM) {
                                    throw new RuntimeException("结束值不能为空或为0以及负数");
                                }
                                if (!weightOrDistance.getEndNum().toString().matches(BASE_NUM_CHECK)) {
                                    throw new RuntimeException("基础重量或基础距离仅支持输入正数或一位小数");
                                }
                                if (weightOrDistance.getStartNum().compareTo(weightOrDistance.getEndNum()) > CONT_NUM) {
                                    throw new RuntimeException("起始值不能大于结束值");
                                }
                            }
                            if (ObjectUtils.isEmpty(weightOrDistance.getMarkupPrice()) || weightOrDistance.getMarkupPrice().compareTo(BigDecimal.ZERO) == CONT_NUM || weightOrDistance.getMarkupPrice().compareTo(BigDecimal.ZERO) < CONT_NUM) {
                                throw new RuntimeException("加价金额不能为空或为0以及负数");
                            }
                            if (!weightOrDistance.getMarkupPrice().toString().matches(ACCOUNT_NUM_CHECK)) {
                                throw new RuntimeException("加价金额仅支持输入正数或两位小数");
                            }
                        }
                    }
                }
            }
        }
        //        List<String> pricingIdList = pricingList.stream().map(Pricing::getId).collect(Collectors.toList());
        List<String> pricingIdList = new ArrayList<>();
        List<String> pricingDelRuleIds = new ArrayList<>();
        pricingIdList.add(pricing.getId());
        List<PricingRule> pricingRuleList = pricingRuleRest.getPricingRuleListByIds(pricingIdList);
//        Map<String,PricingRule> pricingRuleMap = pricingRuleList.stream().collect(Collectors.toMap(i -> i.getId() + i, j -> j, (k1, k2) -> k1));
        List<String> pricingRuleIdList = pricingRuleList.stream().map(PricingRule::getId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(pricingRuleIdList)) {
            List<PricingRuleRange> pricingRuleRangeList = pricingRuleRangeRest.getPricingRuleRangeByIds(pricingRuleIdList).stream().sorted(Comparator.comparingInt(PricingRuleRange::getSort)).collect(Collectors.toList());
            List<String> pricingRuleRangeIdList = pricingRuleRangeList.stream().map(PricingRuleRange::getId).collect(Collectors.toList());
            //        Map<String,PricingRuleRange> pricingRuleRangeMap = pricingRuleRangeList.stream().collect(Collectors.toMap(i -> i.getId() + i, j -> j, (k1, k2) -> k1));
            Date date = new Date();
            //循环根据该定价之前的id查询出来的所有子表的值

            if (!CollectionUtils.isEmpty(pricingEditRequest.getPricingRuleRangeArray())) {
                //遍历传进来的参数进行比对
                for (PricingEditRequest.PricingRuleRange pricingRuleRange : pricingEditRequest.getPricingRuleRangeArray()) {
                    //传进来有定价规则id主键说明有数据回显,只做修改和删除操作,否则新增
                    //如果有删除标识有id但是定价类型没有的统一做删除操作
                    if (StringUtils.isNotBlank(pricingRuleRange.getPricingRuleId()) && (DEL_NUM.equals(pricingRuleRange.getDelNum()) || pricingRuleRange.getType() == null)) {
                        pricingDelRuleIds.add(pricingRuleRange.getPricingRuleId());
                        continue;
                    }
                    if (StringUtils.isBlank(pricingRuleRange.getPricingRuleId()) && !ObjectUtils.isEmpty(pricingRuleRange.getType())) {
                        //新增
                        PricingRule pricingRuleDemo = new PricingRule();
                        String joinId = String.join("", UUID.randomUUID().toString().split("-"));
                        pricingRuleDemo.setId(joinId);
                        pricingRuleDemo.setType(pricingRuleRange.getType());
                        pricingRuleDemo.setBaseNum(pricingRuleRange.getBaseNum());
                        pricingRuleDemo.setCreateTime(date);
                        pricingRuleDemo.setUpdateTime(date);
                        pricingRuleDemo.setPricingId(pricingEditRequest.getId());
                        pricingRuleRest.insert(pricingRuleDemo);
                        if (!CollectionUtils.isEmpty(pricingRuleRange.getWeightOrDistanceList())) {
                            for (PricingEditRequest.PricingRuleRange.WeightOrDistance weightOrDistance : pricingRuleRange.getWeightOrDistanceList()) {
                                PricingRuleRange pricingRuleRangeDemo = new PricingRuleRange();
                                pricingRuleRangeDemo.setRangeTypes(weightOrDistance.getRangeTypes());
                                pricingRuleRangeDemo.setStartNum(weightOrDistance.getStartNum());
                                pricingRuleRangeDemo.setEndNum(weightOrDistance.getEndNum());
                                pricingRuleRangeDemo.setMarkupPrice(weightOrDistance.getMarkupPrice());
                                pricingRuleRangeDemo.setSort(weightOrDistance.getSort());
                                pricingRuleRangeDemo.setCreateTime(date);
                                pricingRuleRangeDemo.setUpdateTime(date);
                                pricingRuleRangeDemo.setPricingRuleId(joinId);
                                pricingRuleRangeRest.insertRuleRangeDemo(pricingRuleRangeDemo);
                            }
                        }
                        continue;
                    }
                    if (!CollectionUtils.isEmpty(pricingRuleList)) {
                        for (PricingRule pricingRule : pricingRuleList) {
                            if (StringUtils.isNotBlank(pricingRuleRange.getPricingRuleId()) && !pricingRule.getId().equals(pricingRuleRange.getPricingRuleId())) {
                                continue;
                            }
                            //如果定价规则主键id一样,那么再比较里面的值是否一致,一致就不动,不一致就修改
//                            if (pricingRuleRange.getPricingRuleId().equals(pricingRule.getId())) {
                            //传进来的数组类型与数据库不一样,修改类型
                            if (!ObjectUtils.isEmpty(pricingRuleRange.getType()) && !ObjectUtils.isEmpty(pricingRule.getType()) && !pricingRuleRange.getType().equals(pricingRule.getType())) {
                                PricingRule pricingRuleDemo = new PricingRule();
                                pricingRuleDemo.setId(pricingRuleRange.getPricingRuleId());
                                if (ObjectUtils.isEmpty(pricingRuleRange.getType())) {
                                    throw new RuntimeException("定价规则类型不能为空");
                                }
                                pricingRuleDemo.setType(pricingRuleRange.getType());
                                pricingRuleDemo.setUpdateTime(date);
                                pricingRuleRest.updatePricingRule(pricingRuleDemo);
                            }
                            if (!ObjectUtils.isEmpty(pricingRuleRange.getBaseNum()) && !ObjectUtils.isEmpty(pricingRule.getBaseNum()) && pricingRuleRange.getBaseNum().compareTo(pricingRule.getBaseNum()) != 0) {
                                PricingRule pricingRuleDemo = new PricingRule();
                                pricingRuleDemo.setId(pricingRuleRange.getPricingRuleId());
                                if (pricingRuleRange.getBaseNum().compareTo(BigDecimal.ZERO) == 0) {
                                    throw new RuntimeException("基础重量或基础距离不能为空");
                                }
                                pricingRuleDemo.setBaseNum(pricingRuleRange.getBaseNum());
                                pricingRuleRest.updatePricingRule(pricingRuleDemo);
                            }

                        }
                    }
                    //循环的传进来的数组内这一子对象(重量或者距离类型分支下)的子数组
                    for (int i = 0; i < pricingRuleRange.getWeightOrDistanceList().size(); i++) {
                        //传进来的子数组里面的子元素
                        PricingEditRequest.PricingRuleRange.WeightOrDistance weightOrDistance = pricingRuleRange.getWeightOrDistanceList().get(i);
                        //遍历根据定价规则查出来的定价明细表
                        if (StringUtils.isBlank(weightOrDistance.getPricingRuleRangeId()) && !ObjectUtils.isEmpty(weightOrDistance.getRangeTypes())) {
                            //如果传进来的子表id为空但是区间,大于类型字段有值,那么做子表的新增操作
                            PricingRuleRange pricingRuleRangeDemo = new PricingRuleRange();
                            if (weightOrDistance.getStartNum().compareTo(BigDecimal.ZERO) == 0) {
                                throw new RuntimeException("开始值不能为空");
                            }
                            if (ObjectUtils.isEmpty(weightOrDistance.getSort())) {
                                throw new RuntimeException("排序字段不能为空");
                            }
                            if (weightOrDistance.getMarkupPrice().compareTo(BigDecimal.ZERO) == 0) {
                                throw new RuntimeException("加价金额不能为空");
                            }
//                                        if(weightOrDistance.getPricingRuleRangeId().equals()){
//
//                                        }
                            pricingRuleRangeDemo.setRangeTypes(weightOrDistance.getRangeTypes());
                            pricingRuleRangeDemo.setStartNum(weightOrDistance.getStartNum());
                            pricingRuleRangeDemo.setEndNum(weightOrDistance.getEndNum());
                            pricingRuleRangeDemo.setMarkupPrice(weightOrDistance.getMarkupPrice());
                            pricingRuleRangeDemo.setSort(weightOrDistance.getSort());
                            pricingRuleRangeDemo.setCreateTime(date);
                            pricingRuleRangeDemo.setUpdateTime(date);
                            pricingRuleRangeDemo.setPricingRuleId(pricingRuleRange.getPricingRuleId());
                            pricingRuleRangeRest.insertRuleRangeDemo(pricingRuleRangeDemo);
                        }
                        for (PricingRuleRange ruleRange : pricingRuleRangeList) {
                            if (StringUtils.isNotBlank(weightOrDistance.getPricingRuleRangeId())) {
                                if (!pricingRuleRange.getPricingRuleId().equals(ruleRange.getPricingRuleId())) {
                                    continue;
                                }
                                //如果子元素的主键id也就是定价规则明细表的id不为空,那么从查出来的数据库里总的主键id里移除掉该id,为删除做准备
                                pricingRuleRangeIdList.remove(weightOrDistance.getPricingRuleRangeId());
                                //如果传进来的定价明细表的id子项和数据库里查到的id主键一致,那么做更新操作
                                if (weightOrDistance.getPricingRuleRangeId().equals(ruleRange.getId())) {
                                    if (!ObjectUtils.isEmpty(weightOrDistance.getRangeTypes()) && !ObjectUtils.isEmpty(ruleRange.getRangeTypes()) && !weightOrDistance.getRangeTypes().equals(ruleRange.getRangeTypes())) {
                                        PricingRuleRange pricingRuleRangeDemo = new PricingRuleRange();
                                        pricingRuleRangeDemo.setId(weightOrDistance.getPricingRuleRangeId());
                                        pricingRuleRangeDemo.setUpdateTime(date);
                                        if (ObjectUtils.isEmpty(weightOrDistance.getRangeTypes())) {
                                            throw new RuntimeException("范围区间不能为空");
                                        }
                                        pricingRuleRangeDemo.setRangeTypes(weightOrDistance.getRangeTypes());
                                        pricingRuleRangeRest.updatePricingRuleRangeDemo(pricingRuleRangeDemo);
                                    }
                                    if (!ObjectUtils.isEmpty(weightOrDistance.getStartNum()) && !ObjectUtils.isEmpty(ruleRange.getStartNum()) && weightOrDistance.getStartNum().compareTo(ruleRange.getStartNum()) != 0) {
                                        PricingRuleRange pricingRuleRangeDemo = new PricingRuleRange();
                                        pricingRuleRangeDemo.setUpdateTime(date);
                                        pricingRuleRangeDemo.setId(weightOrDistance.getPricingRuleRangeId());
                                        if (weightOrDistance.getStartNum().compareTo(BigDecimal.ZERO) == 0) {
                                            throw new RuntimeException("开始值不能为空");
                                        }
                                        pricingRuleRangeDemo.setStartNum(weightOrDistance.getStartNum());
                                        pricingRuleRangeRest.updatePricingRuleRangeDemo(pricingRuleRangeDemo);
                                    }

                                    if (weightOrDistance.getEndNum() != null) {
                                        if (!ObjectUtils.isEmpty(weightOrDistance.getEndNum()) && !ObjectUtils.isEmpty(ruleRange.getEndNum()) && weightOrDistance.getEndNum().compareTo(ruleRange.getEndNum()) != 0) {
                                            PricingRuleRange pricingRuleRangeDemo = new PricingRuleRange();
                                            pricingRuleRangeDemo.setUpdateTime(date);
                                            pricingRuleRangeDemo.setId(weightOrDistance.getPricingRuleRangeId());
                                            pricingRuleRangeDemo.setEndNum(weightOrDistance.getEndNum());
                                            pricingRuleRangeRest.updatePricingRuleRangeDemo(pricingRuleRangeDemo);
                                        }
                                    }
                                    if (!ObjectUtils.isEmpty(weightOrDistance.getSort()) && !ObjectUtils.isEmpty(ruleRange.getSort()) && !weightOrDistance.getSort().equals(ruleRange.getSort())) {
                                        PricingRuleRange pricingRuleRangeDemo = new PricingRuleRange();
                                        pricingRuleRangeDemo.setId(weightOrDistance.getPricingRuleRangeId());
                                        if (ObjectUtils.isEmpty(weightOrDistance.getSort())) {
                                            throw new RuntimeException("排序字段不能为空");
                                        }
                                        pricingRuleRangeDemo.setUpdateTime(date);
                                        pricingRuleRangeDemo.setSort(weightOrDistance.getSort());
                                        pricingRuleRangeRest.updatePricingRuleRangeDemo(pricingRuleRangeDemo);
                                    }
                                    if (!ObjectUtils.isEmpty(weightOrDistance.getMarkupPrice()) && !ObjectUtils.isEmpty(ruleRange.getMarkupPrice()) && weightOrDistance.getMarkupPrice().compareTo(ruleRange.getMarkupPrice()) != 0) {
                                        PricingRuleRange pricingRuleRangeDemo = new PricingRuleRange();
                                        pricingRuleRangeDemo.setUpdateTime(date);
                                        pricingRuleRangeDemo.setId(weightOrDistance.getPricingRuleRangeId());
                                        if (weightOrDistance.getMarkupPrice().compareTo(BigDecimal.ZERO) == 0) {
                                            throw new RuntimeException("加价金额不能为空");
                                        }
                                        pricingRuleRangeDemo.setMarkupPrice(weightOrDistance.getMarkupPrice());
                                        pricingRuleRangeRest.updatePricingRuleRangeDemo(pricingRuleRangeDemo);
                                    }
                                }

                            }
                        }
                    }
                }

            }
            if (!CollectionUtils.isEmpty(pricingRuleRangeIdList)) {
                pricingRuleRangeRest.delRuleRangeDemo(pricingRuleRangeIdList);
            }
            if (!CollectionUtils.isEmpty(pricingDelRuleIds)) {
                pricingRuleRest.deletePricingRule(pricingDelRuleIds);
                pricingRuleRangeRest.delRuleRangeDemo(pricingDelRuleIds);
            }
        }
        if (CollectionUtils.isEmpty(pricingRuleIdList) && StringUtils.isNotBlank(pricingEditRequest.getId()) && !CollectionUtils.isEmpty(pricingEditRequest.getPricingRuleRangeArray())) {
            //新增
            Date date = new Date();
            for (PricingEditRequest.PricingRuleRange pricingRuleRange : pricingEditRequest.getPricingRuleRangeArray()) {
                //传进来有定价规则id主键说明有数据回显,只做修改和删除操作,否则新增
                //如果有删除标识有id但是定价类型没有的统一做删除操作
                if (StringUtils.isNotBlank(pricingRuleRange.getPricingRuleId()) && (DEL_NUM.equals(pricingRuleRange.getDelNum()) || pricingRuleRange.getType() == null)) {
                    continue;
                }
                PricingRule pricingRuleDemo = new PricingRule();
                String joinId = String.join("", UUID.randomUUID().toString().split("-"));
                pricingRuleDemo.setId(joinId);
                pricingRuleDemo.setType(pricingRuleRange.getType());
                pricingRuleDemo.setBaseNum(pricingRuleRange.getBaseNum());
                pricingRuleDemo.setCreateTime(date);
                pricingRuleDemo.setUpdateTime(date);
                pricingRuleDemo.setPricingId(pricingEditRequest.getId());
                pricingRuleRest.insert(pricingRuleDemo);
                if (!CollectionUtils.isEmpty(pricingRuleRange.getWeightOrDistanceList())) {
                    for (PricingEditRequest.PricingRuleRange.WeightOrDistance weightOrDistance : pricingRuleRange.getWeightOrDistanceList()) {
                        PricingRuleRange pricingRuleRangeDemo = new PricingRuleRange();
                        pricingRuleRangeDemo.setRangeTypes(weightOrDistance.getRangeTypes());
                        pricingRuleRangeDemo.setStartNum(weightOrDistance.getStartNum());
                        pricingRuleRangeDemo.setEndNum(weightOrDistance.getEndNum());
                        pricingRuleRangeDemo.setMarkupPrice(weightOrDistance.getMarkupPrice());
                        pricingRuleRangeDemo.setSort(weightOrDistance.getSort());
                        pricingRuleRangeDemo.setCreateTime(date);
                        pricingRuleRangeDemo.setUpdateTime(date);
                        pricingRuleRangeDemo.setPricingRuleId(joinId);
                        pricingRuleRangeRest.insertRuleRangeDemo(pricingRuleRangeDemo);
                    }
                }
            }
        }

        //已存在的特殊定价ID集合
        List<String> specialPricingIds = new LinkedList<String>();
        //检查特殊定价是否重复
        if (CollUtil.isNotEmpty(pricingEditRequest.getSpecialPricingReqList())) {
            assert !hasDuplicates(pricingEditRequest.getSpecialPricingReqList()) : "特殊定价存在重复航线";
            for (SpecialPricingReq specialPricingReq : pricingEditRequest.getSpecialPricingReqList()) {
                BigDecimal specialPricingPrice = specialPricingReq.getPrice();
                if (specialPricingPrice.compareTo(new BigDecimal("99999.99")) > 0 || specialPricingPrice.compareTo(new BigDecimal("0")) <= 0) {
                    throw new RuntimeException("特殊定价仅支持输入数字，支持小数，最多两位小数，输入范围(0,99999.99)");
                }
                if (ObjectUtil.isNull(specialPricingReq.getId())) {
                    specialPricingReq.setCreateTime(LocalDateTime.now());
                    specialPricingReq.setUpdateTime(LocalDateTime.now());
                    specialPricingReq.setPricingId(pricingEditRequest.getId());
                    specialPricingReq.setId(String.join("", UUID.randomUUID().toString().split("-")));
                } else {
                    specialPricingIds.add(specialPricingReq.getId());
                }
            }
            if (!specialPricingRest.saveOrUpdateSpBatch(pricingEditRequest.getId(), specialPricingIds, pricingEditRequest.getSpecialPricingReqList())) {
                throw new RuntimeException("定价更新失败");
            }
        } else {
            specialPricingRest.saveOrUpdateSpBatch(pricingEditRequest.getId(), specialPricingIds, pricingEditRequest.getSpecialPricingReqList());
        }
    }

    /**
     * 判断特殊定价航线是否重复
     *
     * @return
     */
    private static Boolean hasDuplicates(List<SpecialPricingReq> specialPricingReqList) {
        //将所有双向航线拆分成单向航线
        LinkedList<SpecialPricingReq> specialPricingReqs = new LinkedList<>();
        specialPricingReqList.forEach(item -> {
            if (item.getIsItBidirectional() == 1) {
                SpecialPricingReq specialPricingReq = new SpecialPricingReq();
                specialPricingReq.setLandingCode(item.getLandingCode());
                specialPricingReq.setTakeoffCode(item.getTakeoffCode());
                specialPricingReqs.add(specialPricingReq);
                SpecialPricingReq specialPricingReq1 = new SpecialPricingReq();
                specialPricingReq1.setLandingCode(item.getTakeoffCode());
                specialPricingReq1.setTakeoffCode(item.getLandingCode());
                specialPricingReqs.add(specialPricingReq1);
            } else {
                specialPricingReqs.add(item);
            }
        });
        Map<String, Long> groupedByCodes = specialPricingReqs.stream()
                .collect(Collectors.groupingBy(
                        p -> p.getLandingCode() + p.getTakeoffCode(),
                        Collectors.counting()
                ));
        return groupedByCodes.values().stream().anyMatch(count -> count > 1);
    }

    @Override
    public void disablePricing(IdRequest idRequest) {
        Pricing pricing = pricingMapper.selectById(idRequest.getId());
        if (ObjectUtils.isEmpty(pricing)) {
            throw new RuntimeException("记录不存在");
        }
        if (pricing.getProductType() == 0 || pricing.getProductType() == 1) {
            throw new RuntimeException("【同城即时达】、【跨城飞送】不可失效");
        }
        pricing.setEnable(false);
        pricing.setUpdateTime(new Date());
        pricingMapper.updateById(pricing);
    }
}
